import pandas as pd
import numpy as np

# 创建示例数据：模拟电商销售记录
data = {
    'date': pd.date_range('2025-10-01', periods=100, freq='D'),
    'product_category': np.random.choice(['电子产品', '服装', '食品', '家居'], 100),
    'region': np.random.choice(['华北', '华东', '华南', '西部'], 100),
    'sales_amount': np.random.randint(100, 5000, 100),
    'quantity': np.random.randint(1, 50, 100),
    'sales_person': np.random.choice(['张三', '李四', '王五'], 100)
}
df = pd.DataFrame(data)
df['unit_price'] = df['sales_amount'] / df['quantity']  # 计算单价

print("原始数据前5行：")
print(df.head())
print("\n数据形状:", df.shape)

# 1. 单列分组统计
print("\n1. 按产品类别统计总销售额和平均单价：")
category_stats = df.groupby('product_category').agg({
    'sales_amount': 'sum',
    'unit_price': 'mean', # 此处取的平均值，不是加权平均值，实际是不准确的
    'quantity': 'count'
}).round(2)
print(category_stats)

# 2. 多列分组统计
print("\n2. 按区域和产品类别统计：")
region_category_stats = df.groupby(['region', 'product_category']).agg({
    'sales_amount': ['sum', 'mean', 'count'],
    'quantity': 'sum'
})
print(region_category_stats)

# 3. 对特定列分组计算
print("\n3. 各区域销售额排名：")
region_rank = df.groupby('region')['sales_amount'].sum().sort_values(ascending=False)
print(region_rank)

# 4. 使用自定义聚合函数
print("\n4. 各销售人员的业绩统计：")
def sales_range(x):
    return x.max() - x.min()

sales_stats = df.groupby('sales_person').agg({
    'sales_amount': [('总销售额', 'sum'), 
               ('平均销售额', 'mean'), 
               ('极差', sales_range)],
    'quantity': 'sum'
}).round(2)
print(sales_stats)

# 5. 分组后迭代访问
print("\n5. 遍历各产品类别的数据：")
for name, group in df.groupby('product_category'):
    print(f"\n产品类别: {name}, 记录数: {len(group)}")
    print(f"平均销售额: {group['sales_amount'].mean():.2f}")

# 6. 分组后过滤（保留销售额总和超过10000的组）
print("\n6. 筛选高销售额产品类别（总销售额 > 10000）：")
high_sales_categories = df.groupby('product_category').filter(
    lambda x: x['sales_amount'].sum() > 10000
)
print(f"筛选后数据形状: {high_sales_categories.shape}")

# 7. 使用transform添加分组统计值到原数据
print("\n7. 添加各产品类别的平均销售额到原数据：")
df['category_avg_sales'] = df.groupby('product_category')['sales_amount'].transform('mean')
print(df[['product_category', 'sales_amount', 'category_avg_sales']].head(10))

# 8. 分组大小和唯一值统计
print("\n8. 各区域销售情况概览：")
print("各区域记录数:")
print(df.groupby('region').size())
print("\n各区域销售的唯一产品类别数:")
print(df.groupby('region')['product_category'].nunique())


"""
agg详解
# 常用数值聚合函数
df.groupby('product_category').agg({
    'sales_amount': [
        'sum',        # 求和
        'mean',       # 平均值
        'median',     # 中位数
        'min',        # 最小值
        'max',        # 最大值
        'std',        # 标准差
        'var',        # 方差
        'sem',        # 标准误差
        'prod',       # 乘积
        'count',      # 计数（非空值）
        'size'        # 计数（包括空值）
    ]
})

# 排名和极值函数(大多数类型都支持)
df.groupby('product_category').agg({
    'sales_amount': [
        'first',      # 第一个值
        'last',       # 最后一个值
        'nth',        # 第n个值（需指定参数）
        'idxmin',     # 最小值索引
        'idxmax',     # 最大值索引
        'rank',       # 排名
        'pct_change'  # 百分比变化
    ]
})


# 如果数据中有文本列
df.groupby('product_category').agg({
    'product_name': [
        'count',      # 非空计数
        'nunique',    # 唯一值数量
        'size',       # 总计数
        lambda x: ', '.join(x.unique()),  # 连接唯一值
        lambda x: x.mode().iloc[0] if not x.mode().empty else None  # 众数
    ]
})

# 时间序列聚合（针对时间列）
df.groupby('product_category').agg({
    'date': [
        'min',        # 最早日期
        'max',        # 最晚日期
        'nunique',    # 唯一日期数
        lambda x: (x.max() - x.min()).days  # 时间跨度（天）
    ]
})

"""
